package org.example.travel_web.controller.admin;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.example.travel_web.dto.PageResult;
import org.example.travel_web.dto.category.CategoryReq;
import org.example.travel_web.dto.category.DelReq;
import org.example.travel_web.dto.category.PageReq;
import org.example.travel_web.dto.category.PageResp;
import org.example.travel_web.entity.AttractionCategoriesET;
import org.example.travel_web.entity.NewsCategoriesET;
import org.example.travel_web.entity.RouteCategoriesET;
import org.example.travel_web.exception.RunException;
import org.example.travel_web.service.AttractionCategoriesService;
import org.example.travel_web.service.NewsCategoriesService;
import org.example.travel_web.service.RouteCategoriesService;
import org.springframework.web.bind.annotation.*;

import java.util.function.Supplier;

@RestController
@RequestMapping("/admin/category")
@Tag(name = "分类管理")
public class CategoryController {

    @Resource
    private NewsCategoriesService newsCategoriesService;
    @Resource
    private AttractionCategoriesService attractionCategoriesService;
    @Resource
    private RouteCategoriesService routeCategoriesService;

    @GetMapping("/news")
    @Operation(summary = "资讯分类分页")
    public PageResult<PageResp> newsCategoriesPageResult(@Valid PageReq req) {
        return newsCategoriesService.pageResult(req);
    }

    @GetMapping("/attraction")
    @Operation(summary = "景点分类分页")
    public PageResult<PageResp> attractionCategoriesPageResult(@Valid PageReq req) {
        return attractionCategoriesService.pageResult(req);
    }

    @GetMapping("/route")
    @Operation(summary = "路线分类分页")
    public PageResult<PageResp> routeCategoriesPageResult(@Valid PageReq req) {
        return routeCategoriesService.pageResult(req);
    }

    @PostMapping
    @Operation(summary = "新增类别")
    public void addCategory(@Valid CategoryReq req) {
        boolean save = false;
        switch (req.getType()) {
            case NEWS -> {
                check(() -> {
                    LambdaQueryWrapper<NewsCategoriesET> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(NewsCategoriesET::getName, req.getName());
                    return newsCategoriesService.exists(queryWrapper);
                });
                save = newsCategoriesService.save(BeanUtil.toBean(req, NewsCategoriesET.class));
            }
            case ATTRACTION -> {
                check(() -> {
                    LambdaQueryWrapper<AttractionCategoriesET> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(AttractionCategoriesET::getName, req.getName());
                    return attractionCategoriesService.exists(queryWrapper);
                });
                save = attractionCategoriesService.save(BeanUtil.toBean(req, AttractionCategoriesET.class));
            }
            case ROUTE -> {
                check(() -> {
                    LambdaQueryWrapper<RouteCategoriesET> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(RouteCategoriesET::getName, req.getName());
                    return routeCategoriesService.exists(queryWrapper);
                });
                save = routeCategoriesService.save(BeanUtil.toBean(req, RouteCategoriesET.class));
            }
        }
        if (!save) {
            throw new RunException("新增类别失败");
        }
    }

    @PutMapping
    @Operation(summary = "修改类别")
    public void updateCategory(@Valid CategoryReq req) {
        if (req.getCategoryId() == null) {
            throw new RunException("类别id不能为空");
        }
        boolean update = false;
        switch (req.getType()) {
            case NEWS -> {
                check(() -> {
                    LambdaQueryWrapper<NewsCategoriesET> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(NewsCategoriesET::getName, req.getName());
                    queryWrapper.ne(NewsCategoriesET::getCategoryId, req.getCategoryId());
                    return newsCategoriesService.exists(queryWrapper);
                });
                update = newsCategoriesService.updateById(BeanUtil.toBean(req, NewsCategoriesET.class));
            }
            case ATTRACTION -> {
                check(() -> {
                    LambdaQueryWrapper<AttractionCategoriesET> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(AttractionCategoriesET::getName, req.getName());
                    queryWrapper.ne(AttractionCategoriesET::getCategoryId, req.getCategoryId());
                    return attractionCategoriesService.exists(queryWrapper);
                });
                update = attractionCategoriesService.updateById(BeanUtil.toBean(req, AttractionCategoriesET.class));
            }
            case ROUTE -> {
                check(() -> {
                    LambdaQueryWrapper<RouteCategoriesET> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(RouteCategoriesET::getName, req.getName());
                    queryWrapper.ne(RouteCategoriesET::getCategoryId, req.getCategoryId());
                    return routeCategoriesService.exists(queryWrapper);
                });
                update = routeCategoriesService.updateById(BeanUtil.toBean(req, RouteCategoriesET.class));
            }
        }
        if (!update) {
            throw new RunException("修改类别失败");
        }
    }

    @DeleteMapping
    @Operation(summary = "删除类别")
    public void delCategory(@Valid DelReq req) {
        boolean remove = false;
        switch (req.getType()) {
            case NEWS -> remove = newsCategoriesService.removeByIds(req.getCategoryIds());
            case ATTRACTION -> remove = attractionCategoriesService.removeByIds(req.getCategoryIds());
            case ROUTE -> remove = routeCategoriesService.removeByIds(req.getCategoryIds());
        }
        if (!remove) {
            throw new RunException("删除类别失败");
        }
    }

    private void check(Supplier<Boolean> supplier) {
        if (supplier.get()) {
            throw new RunException("类别已存在");
        }
    }
}
